﻿namespace Pibby.Core.IO
{
	using System.IO;
	
	internal class FileDiscoverer : IDiscoverFiles
	{
		#region Constructors

		public FileDiscoverer(IFileVisitor visitor, SearchOption searchOption)
			: this(visitor, searchOption, FileFilterConstants.AllFiles)
		{
		}

		public FileDiscoverer(IFileVisitor visitor, SearchOption searchOption, string mask)
		{
			this.Visitor = visitor;
			this.SearchOption = searchOption;
			this.SearchMask = mask;
		}

		#endregion

		#region Properties

		public string SearchMask
		{
			get;
			set;
		}

		public SearchOption SearchOption
		{
			get;
			set;
		}

		private IFileVisitor Visitor
		{
			get;
			set;
		}

		#endregion

		#region Methods

		public bool Process(IFolder folder)
		{
			Contract.EnsureIsNotNull(folder, "IFolder cannot be null");
			Contract.EnsureIsNotNull(this.Visitor, "Visitor not set");

			bool keepGoing = true;

			this.Visitor.Entering(folder);

			if (this.SearchOption == SearchOption.AllDirectories)
			{
				try
				{
					foreach (IFolder subDir in folder.GetSubfolders())
					{
						if (!this.Process(subDir))
						{
							keepGoing = false;
							break;
						}
					}
				}
				catch (System.UnauthorizedAccessException)
				{
					// swallow
				}
			}

			if (keepGoing)
			{
				try
				{
					foreach (IFile file in folder.GetFiles(this.SearchMask))
					{
						if (!this.Visitor.Visit(file))
						{
							keepGoing = false;
							break;
						}
					}
				}
				catch (System.UnauthorizedAccessException)
				{
					// swallow
				}
			}

			this.Visitor.Leaving(folder);

			return keepGoing;
		}

		#endregion
	}
}
